package com.wnxy.sddfp.access.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wnxy.sddfp.access.entity.TradeLog;
import com.wnxy.sddfp.access.mapper.TradeLogMapper;
import com.wnxy.sddfp.access.service.ITradeLogService;
import com.wnxy.sddfp.access.utils.EncryptUtil;
import com.wnxy.sddfp.common.model.dto.bank.BankCardAddDTO;
import com.wnxy.sddfp.common.model.dto.bank.BankReqDto;
import com.wnxy.sddfp.common.model.dto.bank.SignatureDto;
import com.wnxy.sddfp.common.model.result.BaseResult;
import com.wnxy.sddfp.common.model.vo.BorrowSyncRecordVo;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;

/**
 * <p>
 * 托管系统交易记录表 服务实现类
 * </p>
 *
 * @author yellow docker
 * @since 2024-07-31
 */
@Service
@Slf4j
public class TradeLogServiceImpl extends ServiceImpl<TradeLogMapper, TradeLog> implements ITradeLogService {
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public BaseResult syncBorrowRecord(BorrowSyncRecordVo borrowSyncRecordVo) {

        // 1、保存日志
        TradeLog tradeLog = new TradeLog();

        // 流水号
        tradeLog.setReqCode(borrowSyncRecordVo.getReqCode());
        // 请求的类型
        tradeLog.setReqType("SYNC_BORROW");
        // 主体  userId
        tradeLog.setObjectId(borrowSyncRecordVo.getUserId());
        // 创建时间
        tradeLog.setCreateDate(LocalDateTime.now());
        // 确认时间
        tradeLog.setConfirmDate(LocalDateTime.now());
        // 同步状态默认是0  (银行返回结果 需要更新状态1 )
        tradeLog.setSynchronizeStatus(0);

        save(tradeLog);

        // 银行返回结果更新的数据
//        tradeLog.setResponseData("");

        // 2、远程调用银行 系统
        // 2.1 请求基础路径；作为完成路径的一部分
        String url = "http://localhost:5600/service";
        // 2.2 发送数据给银行系统  看银行系统
        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        // 请求数据:reqData
        // String url = "http://ip:5600/service?serviceName=SYNC_BORROW_RECODE&reqData=xxx";

        // 2.3 请求数据 - 对象转换为JSON， 使用alibaba提供的fastjson工具类(银行托管也是使用fastjson)
        String str = JSON.toJSONString(borrowSyncRecordVo);
        // 2.4 对象加密处理： str ---> Base64编码 ---> URL编码 ---> 目标str
        // str ---> Base64编码
        String base64Str = EncryptUtil.encodeUTF8StringBase64(str);
        // Base64编码 ---> URL编码
        String reqData = EncryptUtil.encodeURL(base64Str);

        // url:  /service    serviceName= xxx服务(SYNC_BORROW_RECODE)
        url = "http://localhost:5600/service?serviceName=SYNC_BORROW_RECORD&reqData=" + reqData;
        log.info("发送数据的url:{}", url);

        // 银行系统使用的是 @RestController 把对象都转成 json 字符串
        // 发送远程调用
        String respBody = restTemplate.getForObject(url, String.class);

        log.info("银行系统返回的数据:{}", respBody);
        // {"respData":{"respCode":"00000","respMsg":"成功","status":1,"requestNo":"REQ_208f14ff-b"}}
        BankReqDto bankReqDto = JSON.parseObject(respBody, BankReqDto.class);
        // 拿到字符串解析
        BaseResult baseResult = JSON.parseObject(bankReqDto.getRespData(), BaseResult.class);
        log.info("银行系统返回的数据进行解析:{}", baseResult);
        String respMsg = baseResult.getRespMsg();
        // StringUtils.hasText() 字符串判空处理
        if (StringUtils.hasText(respMsg) && respMsg.equals("成功")) {
            // 更新确认时间
            tradeLog.setConfirmDate(LocalDateTime.now());
            // 更新状态
            tradeLog.setSynchronizeStatus(1);
            // 存储 银行系统返回的结果
            tradeLog.setResponseData(respBody);
            // 银行系统返回结果后进行更新
            updateById(tradeLog);
        }
        // 返回银行系统的结果
        return baseResult;
    }


    @SneakyThrows
    @Override
    /**
     * 代理绑定银行卡日志记录。
     * 该方法用于处理银行卡绑定操作，并记录此次操作的相关信息到交易日志中。
     * 同时，生成并返回一个包含请求数据和标识信息的SignatureDto对象。
     * @param bankCardAddDTO 银行卡添加的DTO（数据传输对象），包含请求的详细信息。
     * @return SignatureDto 对象，包含银行URL、平台编号、请求数据和请求标识。
     */
    public SignatureDto proxyBindCardLog(BankCardAddDTO bankCardAddDTO) {
        // 创建交易日志对象，用于记录操作信息。
        // 保存交易记录
        TradeLog tradeLog = new TradeLog();
        // 设置交易日志的各个属性，包括请求码、请求类型、对象ID、创建日期、同步状态、确认日期和响应数据。
        tradeLog.setReqCode(bankCardAddDTO.getReqCode());
        tradeLog.setReqType("USER_BIND_CARD");
        tradeLog.setObjectId(bankCardAddDTO.getUserId());
        tradeLog.setCreateDate(LocalDateTime.now());
        tradeLog.setSynchronizeStatus(0);
        tradeLog.setConfirmDate(LocalDateTime.now());
        tradeLog.setResponseData("");

        // 保存交易日志
        save(tradeLog);

        // 创建SignatureDto对象，用于返回给调用方，包含银行URL、平台编号、请求数据和请求标识。
        // 返回结果
        SignatureDto signatureDto = new SignatureDto();
        signatureDto.setBankUrl("http://localhost:5600/bank/user");
        signatureDto.setPlatformNo("SDDFP");
        // 将bankCardAddDTO对象转换为JSON字符串，作为请求数据。
        signatureDto.setReqData(new ObjectMapper().writeValueAsString(bankCardAddDTO));
        signatureDto.setReqCode(bankCardAddDTO.getReqCode());

        // 返回SignatureDto对象。
        return signatureDto;
    }
}
